﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using System.Data;

namespace CEP
{
    /// <summary>
    /// Esta classe é responsável por gerir todas as notificações
    /// </summary>
    class Notificar
    {

        private bool activo = false; //utilizado para verificar se o processo está a decorrer

        private static Notificar instance = new Notificar();
        private Notificar() { }

        public static Notificar Instance
        {
            get
            {
                return instance;
            }
        }

        /// <summary>
        /// Verifica se o processo de notificação está a decorrer
        /// É utilizado pra prevenir que dois processos estejam a decorrer em paralelo
        /// </summary>
        /// <returns></returns>
        private bool isActivo()
        {
            return activo;
        }

        /// <summary>
        /// Inicia o processo de notificação (tanto para EMAIL como para SMS)
        /// </summary>
        public void init()
        {

            //verificar se o processo está a decorrer
            if (isActivo())
                return;

            Log.Instance.escrever("A vereficar se existem subscricoes por notificar...");

            //activar flag para o precesso correr apenas uma vez!
            activo = true;

            SqlConnection connection = null;
            List<int> notificados = new List<int>();

            try
            {
                //definir ligação
                connection = new SqlConnection(Properties.Settings.Default.extremeEventos);
                //abrir ligação
                connection.Open();

                //definir stored procedure
                SqlCommand command = new SqlCommand("ext.visitantesPorNotificar", connection);

                SqlDataReader reader = command.ExecuteReader();

                while (reader.Read())
                {

                    //definir evento
                    Evento evt = new Evento
                    {
                        id_subscrever_evento = (int)reader["id_subscrever_evento"],
                        id_evento = (int)reader["id_evento"],
                        data_inicio = (DateTime)reader["data_inicio"],
                        data_fim = (DateTime)reader["data_fim"],
                        titulo = reader["titulo"].ToString(),
                        descricao = reader["descricao"].ToString(),
                        morada = reader["morada"].ToString(),
                        codigo_postal = reader["codigo_postal"].ToString(),
                        contato_telefonico = reader["contato_telefonico"].ToString(),
                        email = reader["email"].ToString(),
                        latitude = reader["latitude"].ToString(),
                        longitude = reader["longitude"].ToString(),
                        nome_categoria = reader["nome_categoria"].ToString(),
                        visitante_nome = reader["visitante_nome"].ToString(),
                        visitante_telefone = reader["visitante_telefone"].ToString(),
                        visitante_email = reader["visitante_email"].ToString()
                    };

                    //notificar utilizador via e-mail
                    bool rst_email = NotificarEmail.Instance.enviar(evt);

                    //notificar utilizador via SMS
                    bool rst_sms = NotificarSMS.Instance.enviar(evt);

                    Log.Instance.escrever(String.Format("id_evento: {0}, data_inicio: {1} | email:{2} | sms:{3}", reader["id_evento"], reader["data_inicio"], rst_email, rst_sms));

                    //marcar a subscrição como nutificada 
                    //basta apenas 1 valido para marcar
                    if (rst_sms || rst_email)
                    {
                        notificados.Add(evt.id_subscrever_evento);
                    }

                }

                reader.Close();

                //marcar subscrições como notificadas
                this.marcarNotificados(notificados, connection);

            }
            catch (SqlException e)
            {
                Log.Instance.escrever("Erro: " + e.Message);
            }
            finally
            {
                //fechar ligações
                if (connection != null)
                    connection.Close();

                //desactivar flag
                activo = false;
            }

        }

        /// <summary>
        /// Percorre uma lista de notificadoes, e marca-os na BD como notificadoes
        /// </summary>
        /// <param name="notificados"></param>
        private void marcarNotificados(List<int> notificados, SqlConnection connection)
        {

            try
            {
                //marcar subscrições como notificadas
                if (notificados.Count > 0)
                {
                    //marcar notificados
                    for (var i = 0; i < notificados.Count; i++)
                    {
                        // create a command object identifying
                        // the stored procedure
                        SqlCommand cmd = new SqlCommand("ext.marcarVisitanteComoNotificado", connection);
                        // set the command object so it knows
                        // to execute a stored procedure
                        cmd.CommandType = CommandType.StoredProcedure;
                        // add parameter to command, which
                        // will be passed to the stored procedure
                        cmd.Parameters.Add(new SqlParameter("@id_subscricao", notificados[i]));
                        //execute the command
                        SqlDataReader rdr = cmd.ExecuteReader();
                        rdr.Close();
                    }

                }
            }
            catch (SqlException e)
            {
                Log.Instance.escrever("Erro: " + e.Message);
            }
        }

    }
}
